package  
{
	import com.GCItem;
	import com.GCQuest;
	import com.facebook.graph.Facebook;
	import com.facebook.graph.data.FacebookSession;
	
	import data.*;
	
	import events.GCEvent;
	
	import flash.display.Bitmap;
	import flash.events.Event;
	import flash.net.*;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;
	import flash.ui.Mouse;
	import flash.utils.Dictionary;
	
	import graph.*;
	
	import loading.*;
	
	import org.flixel.FlxG;
	import org.flixel.FlxState;
	
	import ui.textfield.*;
	
	/**
	 * The state right after the game is done loading but before
	 * anything is displayed on the screen
	 */
	public class GCLoginState extends FlxState 
	{
		public static const SHARED_OBJECT_NAME:String = "cse481d-simeconomy-v0.1";
		public static const SHARED_OBJECT_PARAM:String = "username";			// A unique id for this player
		public static const SHARED_OBJECT_PARAM_UNAME:String = "playername";	// Name selected by player

		// Make VERY sure that we start the game just once
		private static var _gameStarted:Boolean;
		
		// Items stored in the flash cache
		private static var _userUniqueId:String;
		private static var _playerName:String;
		
		// A queue to check if all items have loaded successfully
		private static var _loadingQueue:Vector.<uint>;
		
		// List of buildings player built
		// Key: Location
		// Value: Vector of building ids
		private static var _buildings:Dictionary;
		
		// List of all items in player inventories
		// Key: Location (include ship)
		// Value: Some representation of items (a list of GCItems)
		private static var _inventories:Dictionary;
		
		// Stores all info related to player
		private static var _playerData:Dictionary;
		private static var _pid:uint;
		
		// List crew groups, where they are and what they are doing
		// Key: Location (include ship)
		// Value: A list of (task, quantity) struct
		private static var _workers:Dictionary;
		
		// List of ships the player has
		// Key: Unique ship id
		// Value: ShipStruct
		private static var _shipList:Dictionary;
		private static var _currentSid:uint;
		private static var _shipIdQueue:Vector.<uint>;
		private static var _shipDefaultStats:Dictionary;
		
		private static var loadText:TextField = new TextField();
		
		// List of quests the player is performing
		// Key: Unique quest id
		// Value: GCQuest objects
		private static var _questsList:Dictionary;
		
		// A user name selection screen, for new players
		private static var _loginScreen:GCLoginScreen;
		
		// The instance of this login state, deal with the strange mix of static and non-static functions
		private static var _loginStateInstance:GCLoginState;
		
		// Store items since last login, use this in the summary return screen
		private static var _soldSinceLastLogin:Vector.<GCItem>;
		
		private static var _facebookReady:Boolean;
		private static var _facebookUserInfo:Dictionary;
		private static var _facebookFriends:Object;
		
		public static function get facebookReady():Boolean
		{
			return _facebookReady;
		}
		
		public static function get uid():String
		{
			if (_facebookReady)
			{
				return GCLoginState.session().uid;				
			}
			else
			{
				return null;
			}
		}
		
		public static function session():FacebookSession
		{
			if (_facebookReady)
			{
				return Facebook.getSession();
			}
			else
			{
				trace("Facebook is not ready");
				return null;
			}
		}
		
		private static function userInfo(callback:Function, forceRefresh:Boolean = false, uid:String = "me"):void
		{
			if (!_facebookReady)
			{
				trace("User info: Facebook is not ready");
				callback(null);
			}
			else if (!forceRefresh && _facebookUserInfo[uid])
			{
				trace("User info: cached copy returned (" + uid + ")" );
				trace("_facebookUserInfo[uid]: " + _facebookUserInfo[uid]);
				callback(_facebookUserInfo[uid]);
			}
			else
			{
				//Facebook.api("/" + uid, function())
			}
		}
		
		override public function create():void
		{
			_facebookReady = false;
			_facebookUserInfo = new Dictionary();
			_facebookFriends = null;
			
			_loginStateInstance = this;
			_gameStarted = false;
			
			if (GCConstants.FACEBOOK_INTEGRATED)
				fbInit();
			else
				createGame();
		}
		
		/**
		 * Returns true if we have successfully logged in to Facebook
		 */
		private function fbInit():void {
			Facebook.init(GCConstants.FACEBOOK_APP_ID, fbInitHandler);
		}
	
		private function fbInitHandler(success:Object, fail:Object):void {
			var loadFormat:TextFormat = new TextFormat("Arial", 30, GCConstants.COLOR_BROWN, true);
			loadFormat.align = TextFormatAlign.CENTER;
			loadText.defaultTextFormat = loadFormat;
			loadText.selectable = true;// TODO Change back to false
			loadText.y = FlxG.height / 2 - 50;
			loadText.text = "Communicating with server please wait.";
			loadText.width = FlxG.width;
			this.addChild(loadText);
			
				
			if (!success) 
			{
				loadText.text = ("Facebook Init Fail: " + success + ", " + fail);
				Facebook.login(fbLoginHandler);
			}
			else
			{
				_facebookReady = true;
				trace("Facebook.init successful: logged in already");
				
				_userUniqueId = GCConstants.FACEBOOK_ID_PREFIX + GCLoginState.uid;
				createGame();
			}
		}

		private function fbLoginHandler(success:Object, fail:Object):void {
			if (success != null) {
				GCResources.fbSession = (success as FacebookSession);
				_playerName = success.user.name;
				_userUniqueId = GCConstants.FACEBOOK_ID_PREFIX + success.user.id;
				trace("FB: " + _playerName + " AND " + _userUniqueId);
				//createGame();
			} else {
				var loadFormat:TextFormat = new TextFormat("Arial", 30, GCConstants.COLOR_BROWN, true);
				loadFormat.align = TextFormatAlign.CENTER;
				loadText.defaultTextFormat = loadFormat;
				loadText.selectable = false;
				loadText.y = FlxG.height / 3 - 50;
				loadText.text = "Communicating with server please wait.";
				loadText.width = FlxG.width;
				this.addChild(loadText);
				GCResources.fbSession = null; // continue as normal game?
				trace("FB LOGIN FAILED");
			}
		}
		
		public function createGame():void
		{	
			// Initialize our resources
			GCItemData.initialize();
			GCShipData.initialize();
			GCResources.init();
			GCExperienceData.init();
			GCCityData.initialize();
			GCPathData.initialize();
			GCBuildingData.initialize();
			GCQuestData.initialize();
			
			// Initialize the travel graph information
			GCTravelGraph.getInstance().initializeTravelCosts();
			
			// Initialize the textformats
			GCTextField.initTextFormats();
			
			//Play music
			FlxG.playMusic(GCResources.bg_music);
			
			// A crappy loading screen
			var bg:Bitmap = GCResources.getResource("worldMap");
			bg.height = FlxG.height;
			this.addChild(bg);
			var loadFormat:TextFormat = new TextFormat("Arial", 30, GCConstants.COLOR_BROWN, true);
			loadFormat.align = TextFormatAlign.CENTER;
			loadText.defaultTextFormat = loadFormat;
			loadText.selectable = false;
			loadText.y = FlxG.height / 2 - 50;
			loadText.text = "Communicating with server please wait.";
			loadText.width = FlxG.width;
			this.addChild(loadText);
			
			_loadingQueue = new Vector.<uint>();
			_shipIdQueue = new Vector.<uint>();
			_soldSinceLastLogin = new Vector.<GCItem>();
			
			_playerData = new Dictionary();
			_buildings = new Dictionary();
			_inventories = new Dictionary();
			_workers = new Dictionary();
			_shipList = new Dictionary();
			_shipDefaultStats = new Dictionary();
			_questsList = new Dictionary();
			_pid = 0;
			
			if (GCConstants.DEBUG_MODE)
			{
				/* Testing Login Screen */
				_loginScreen = new GCLoginScreen();
				addChild(_loginScreen);
				
				_loginScreen.addEventListener(GCEvent.SELECTED_USER_NAME_EVENT, function(event:Event):void
				{
					// Get the player name from the login screen, add to cache, and remove login screen
					_playerName = _loginScreen.userNameSelected;
					//storeNewPlayerInformation();
					removeChild(_loginScreen);
					
					/*
					 * Transition to the play state, pass along and data we
					 * got to the play logic in next state.
					 */
					startGame();
				});	
				
				return;
			}
			
			var isPlayerReturning:Boolean = checkIfReturningPlayerAndGo();

		}
		
		override public function update():void
		{
			flash.ui.Mouse.show();
		}
		
		/**
		 * Go through actions to put a new player into the game, ask
		 * them for a player name to use and initialize data for them to use.
		 */
		private function initializeNewPlayerData():void
		{
			loadText.text = "add new player";
			
			_loginScreen = new GCLoginScreen();
			addChild(_loginScreen);
			
			_loginScreen.addEventListener(GCEvent.SELECTED_USER_NAME_EVENT, function(event:Event):void
			{
				// Get the player name from the login screen, add to cache, and remove login screen
				_playerName = _loginScreen.userNameSelected;
				if (!GCConstants.FACEBOOK_INTEGRATED)
					storeNewPlayerInformation();
				removeChild(_loginScreen);
				
				// Add new player data to the database
				_loadingQueue.push(0);
				GCUtil.addPlayer(_userUniqueId, GCCityData.CITY_PICAROON, _playerName, onAddedNewPlayer);
			});
		}
		
		/**
		 * Called when we get a callback for initializing a particular new player initialization.
		 */
		private function initializationStageFinished():void
		{
			_loadingQueue.pop();
			if (_loadingQueue.length > 0)
			{
				return;
			}
			
			// Once we know the player has all information initialized, then we store
			// information in the cache
			if (!GCConstants.FACEBOOK_INTEGRATED)
				storeNewPlayerInformation();
			
			// Once all data for a new player has been set, we go through
			// the process of loading it. (A bit redundant, frees us from having
			// to fill up required data structures in a separate path)
			startLoadingData();
		}
		
		private function startLoadingData():void
		{
			// Put first request on the queue
			trace("Starting load from database");
			_loadingQueue.push(0);
			GCUtil.getPlayerInfo(_userUniqueId, onLoadPlayerData);
		}
		
		/**
		 * Function called every time a single loading callback was reached, we will check if all data
		 * was loaded or if we are still waiting for something. If all done, start the game else
		 * we wait some more.
		 */
		private function loadingStageFinished():void
		{
			// Pop an item from the queue
			_loadingQueue.pop();
			if (_loadingQueue.length == 0)
			{
				// Done loading all necessary data, can start the game
				trace("GCLoginState-- Loading from database is complete!");
				startGame();
			}
		}
		
		/**
		 * Start the actual game after all data has been loaded and new player has been initialized.
		 */
		private function startGame():void
		{
			trace("Completed login!!!!!!");
			
			// Only start if the game has not started once already
			if (!_gameStarted)
			{
				loadText.text = "initializing state";
				var playState:GCPlayState = new GCPlayState();
				playState.initializeFromDatabase(_playerData, _shipList, _questsList, _buildings, _workers, _inventories, _soldSinceLastLogin);
				FlxG.state = playState;
				_gameStarted = true;
			}
		}
		
		/**
		 * Callback when a brand new player has entered the game.
		 * _loadingQueue 1
		 * @param	code
		 * @param	data
		 */
		private function onAddedNewPlayer(code:uint, data:Object):void
		{
			loadText.text = "new player was added";
			// Get back a unique player id for this new player
			var id:uint = data["id"];
			_pid = id;
			
			// Now we initialize some starting data for this new player
			// Give them a ship, and give the ship some initial upgrade slots
			_loadingQueue.push(0);
			// queue 2
			var stats:Vector.<uint> = GCShipData.getStatsFromId(GCShipData.SHIP_TYPE_SAILBOAT);
			var speed:uint = stats[0];
			var defense:uint = stats[1];
			var navigation:uint = stats[2];
			var slots:uint = stats[3];
			var hull:uint = stats[4];
			var maintenance:uint = stats[5];
			var fuel:uint = stats[6];
			_shipDefaultStats["defense"] = defense;
			_shipDefaultStats["hull"] = hull;
			_shipDefaultStats["slots"] = slots;
			GCUtil.addShip(_pid, GCShipData.SHIP_TYPE_SAILBOAT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, onAddedShip);
			
			// Give them a warehouse
			_loadingQueue.push(0);
			GCUtil.buildStructure(_pid, GCCityData.CITY_PICAROON, GCBuildingData.BUILDING_WAREHOUSE, onBuiltStructure);
			
			// Give them initial goods
			_loadingQueue.push(0);
			GCUtil.addToInventory(_pid, GCItemData.ITEM_COAL, GCCityData.CITY_PICAROON, 20, onAddedToInventory);
			
			initializationStageFinished();
		}
		
		private function onUpdateCrew(code:uint, data:Object):void
		{
			trace("Updated the crew");
		}
		
		/**
		 * Add a single crew member to the specified location
		 * 
		 * @param	code
		 * @param	data
		 */
		private function onAddCrew(code:uint, data:Object):void
		{
			trace("Added crew");
		}
		
		private function onCompleteQuest(code:uint, data:Object):void
		{
			trace("Ended Quest");
		}
		
		private function onAddQuest(code:uint, data:Object):void
		{
			trace("Added a new quest");
			
			// Get back a unique qid for this quest
			var qid:uint = data["id"];
		}
		
		/**
		 * Adding a brand new ship to the player's collection
		 * 
		 * @param	code
		 * @param	data
		 */
		private function onAddedShip(code:uint, data:Object):void
		{
			loadText.text = "added a ship";
			trace("Added a new ship");
			var shipId:uint = data["id"];
			
			for (var i:uint = 0; i < _shipDefaultStats["slots"]; i++)
			{
				_loadingQueue.push(0);
				GCUtil.equipItemToShip(shipId, i, GCItemData.ITEM_NULL, 0, 0, 0, 0, 0, 0, onAddedUpgrade);
			}
			
			// Must set this ship to be active
			_loadingQueue.push(0);
			GCUtil.changeActiveShip(_pid, shipId, onMakeShipActive);

			initializationStageFinished();
		}
		
		/** THIS IS BROKEN (not returning proper value) **/
		private function onAddedUpgrade(code:uint, data:Object):void
		{
			loadText.text = "added an upgrade";
			trace("Added an upgrade");
			initializationStageFinished();
		}
		
		private function onBuiltStructure(code:uint, data:Object):void
		{
			loadText.text = "added a building";
			trace("Constructed a building");
			initializationStageFinished();
		}
		
		private function onMakeShipActive(code:uint, data:Object):void
		{	
			loadText.text = "making ship active";
			initializationStageFinished();
		}
		
		/**
		 * Adding a brand new item to the inventory. Returns the invItemId for that
		 * particular item (creates a new one if needed)
		 * 
		 * @param	code
		 * @param	data
		 */
		private function onAddedToInventory(code:uint, data:Object):void
		{
			trace("Added a new item to inventory");
			var invItemId:uint = data["id"];
			
			initializationStageFinished();
		}
		
		/**
		 * Callback to load an existing player's data
		 * 
		 * @param	code
		 * @param	data
		 */
		private function onLoadPlayerData(code:uint, data:Object):void
		{
			
			var details:Object = data["details"];
			details = details[0];

			if (code == 1)
			{
				// Pop off the call to this load, it finished but failed
				_loadingQueue.pop();
				
				// Flash cache had something but player did not have an account on the data base???
				initializeNewPlayerData();
				return;
			}
			
			if (code != 0)
			{
				loadText.text = "Sorry, error fetching from database";
			}
			
			_playerData["pid"] = details["id"];
			_playerData["xp"] = details["xp"];
			_playerData["lid"] = details["locId"];
			_playerData["gold"] = details["gold"];
			_playerData["tutorial"] = details["tutorialProgress"];
			_playerData["name"] = details["name"];

			trace("The player id was " + _playerData["pid"]);
			_pid = _playerData["pid"];
			
			// Now we must get information about the the player's buildings, workers, ships,
			// inventories, and quests
			_loadingQueue.push(0);
			GCUtil.getCrewInfo(_pid, onLoadPlayerWorkers);
			_loadingQueue.push(0);
			GCUtil.getShips(_pid, onLoadPlayerShips);
			_loadingQueue.push(0);
			GCUtil.getQuests(_pid, onLoadQuests);
			
			var i:uint;
			for (i = 0; i < GCCityData.NUM_CITIES; i++)
			{
				_loadingQueue.push(0);
				loadInventoryAt(i);
				_loadingQueue.push(0);
				loadBuildingsAt(i);
			}
			
			// Get ship inventory, the "city" is the ship in this case
			_loadingQueue.push(0);
			loadInventoryAt(GCCityData.CITY_SHIP);
			
			loadingStageFinished();
		}
		
		/**
		 * Callback to load all of the quests that a player has in progress.
		 * 
		 * @param	code
		 * @param	data
		 */
		private function onLoadQuests(code:uint, data:Object):void
		{
			loadText.text = "loading quest data";
			var details:Object = data["details"];
			
			for each (var item:Object in details)
			{
				var qid:uint = item["id"];
				var minLeft:uint = item["minLeft"];
				var progress:uint = item["contribution"];
				var lid:uint = item["locId"];
				var tid:uint = item["templateId"];
				var aid:uint = item["fromId"];
				var reqId:uint = item["reqItemId"];
				var reqQty:uint = item["reqItemQty"];
				var rewardId:uint = item["rewItemId"];
				var rewardQty:uint = item["rewItemQty"];
				
				// Will need to later set quest parameters individually based on this data
				var quest:GCQuest = new GCQuest(tid, aid, lid, minLeft, reqId, reqQty, rewardId, rewardQty);
				quest.currentProgress = progress;
				
				_questsList[qid] = quest;
			}
			
			trace("Loaded Quests");
			loadingStageFinished();
		}
		
		/**
		 * Callback to load all of the inventory that a player possesses at a location.
		 * Iterates through a single location at a time
		 * 
		 * @param	code
		 * @param	data
		 */
		private function loadInventoryAt(lid:uint):void
		{
			GCUtil.getInventory(_pid, lid, function(code:uint, data:Object):void
			{
			
				loadText.text = "loading inventory data";
				// List of GCItems
				var inventory:Vector.<GCItem> = new Vector.<GCItem>();
				var details:Object = data["details"];
				
				for each (var item:Object in details)
				{
					var invItemId:uint = item["id"];
					var itemTypeId:uint = item["itemId"];
					var quantity:uint = item["qty"];
					var saleQuantity:uint = item["saleQty"];
					var salePrice:uint = item["salePrice"];
					var isSale:Boolean = false;
					
					var soldQty:uint = item["soldQtySinceNotify"];
					
					var availableQty:uint = quantity - saleQuantity;
					// Add item to the list
					if (availableQty > 0)
					{
						var itemObject:GCItem = new GCItem(invItemId, itemTypeId, availableQty, _playerData["id"], _playerName);
						inventory.push(itemObject);
					}
					
					// Check if item is a sale, and add new object for it if it is
					if (saleQuantity > 0)
					{
						isSale = true;
						var saleItemObject:GCItem = new GCItem(invItemId, itemTypeId, saleQuantity, _playerData["id"], _playerName, salePrice, isSale);
						inventory.push(saleItemObject);
					}
					/**/
					if (soldQty > 0)
					{
						// One of your items sold while you were logged off
						var soldItemObject:GCItem = new GCItem(invItemId, itemTypeId, soldQty,  _playerData["id"], _playerName, salePrice);
						_soldSinceLastLogin.push(soldItemObject);
						
						// Inform the DB that we have noted the transaction took place
						GCUtil.saleNotifyComplete(invItemId, soldQty, function(code:uint, data:Object):void { } );
					}
				}
				
				_inventories[lid] = inventory;
				loadingStageFinished();
			});
		}
		
		/**
		 * Callback to load what buildings the player has. Iterates through each city
		 * one at a time.
		 * 
		 */
		private function loadBuildingsAt(lid:uint):void
		{
			GCUtil.getBuildings(_pid, lid, function(code:uint, data:Object):void
			{
				loadText.text = "loading building data";
				var details:Object = data["details"];
				var buildingsList:Vector.<uint> = new Vector.<uint>();
				
				for each (var item:Object in details)
				{
					trace("Bldg id " + item["id"]);
					item["id"];
					buildingsList.push(item["bldgTypeId"] as uint);
				}
	
				_buildings[lid] = buildingsList;
				
				loadingStageFinished();
			});
		}
		
		/**
		 * Callback to get information about a player's workers.
		 * 
		 * @param	code
		 * @param	data
		 */
		private function onLoadPlayerWorkers(code:uint, data:Object):void
		{	
			loadText.text = "loading workers data";
			var details:Object = data["details"];
			
			for each (var item:Object in details)
			{
				var lid:uint = item["locId"];
				var tid:uint = item["taskId"];
				var quantity:uint = item["qty"];
				
				// If no workers were at a location, create a new struct for
				// that location and populate with (tid, qty) pairings
				if (_workers[lid] == null)
				{
					_workers[lid] = new Vector.<GCCrewLoadObject>();
				}
				
				// Add new object to the list
				(_workers[lid] as Vector.<GCCrewLoadObject>).push(new GCCrewLoadObject(tid, quantity));
				trace(lid + " " + tid + " " + quantity);
			}
			
			// Here _workers contain all needed info about workers
			loadingStageFinished();
		}
		
		/**
		 * Callback to grab data about a player's ships
		 * 
		 * @param	code
		 * @param	data
		 */
		private function onLoadPlayerShips(code:uint, data:Object):void
		{
			loadText.text = "loading ships data";
			var details:Object = data["details"];
			
			for each (var item:Object in details)
			{
				trace("Loaded up a ship");
				var sid:uint = item["id"];
				var type:uint = item["shipTypeId"];
				
				var additionalStatBoost:Vector.<uint> = new Vector.<uint>();
				for (var i:uint = 0; i < 7; i++)
				{
					additionalStatBoost.push(0);
				}
				
				// These are additional permanent boosts in addition to the base stats
				// Are initially zero
				var speed:uint = item["speed"];
				var defense:uint = item["defense"];
				var navigation:uint = item["navigation"];
				var slots:uint = item["slots"];
				var capacity:uint = item["capacity"];
				var maintenance:uint = item["maintenance"];
				var fuelEff:uint = item["fuelEfficiency"];
				
				additionalStatBoost[GCShipData.STAT_SPEED] = speed;
				additionalStatBoost[GCShipData.STAT_DEFENSE] = defense;
				additionalStatBoost[GCShipData.STAT_HULL] = capacity;
				additionalStatBoost[GCShipData.STAT_FUEL_EFFICIENCY] = fuelEff;
				additionalStatBoost[GCShipData.STAT_MAINTENANCE] = maintenance;
				additionalStatBoost[GCShipData.STAT_NAVIGATION] = navigation;
				additionalStatBoost[GCShipData.STAT_SLOTS] = slots;
				//item["consRes1"];
				//item["consQty1"];
				//item["consRes2"];
				//item["consQty2"];
				var active:Boolean = item["active"];
				
				var ship:GCShipLoadObject = new GCShipLoadObject(sid, type, active, additionalStatBoost);
				_shipList[sid] = ship;
				
				_shipIdQueue.push(sid);
			}
			
			if (_shipIdQueue.length > 0)
			{
				_loadingQueue.push(0);
				_currentSid = _shipIdQueue.pop();
				GCUtil.getShipEquipment(_currentSid, onLoadShipUpgrades);
			}
			
			loadingStageFinished();
		}
		
		/**
		 * Function to get ship upgrades
		 * 
		 * @param	code
		 * @param	data
		 */
		private function onLoadShipUpgrades(code:uint, data:Object):void
		{
			var details:Object = data["details"];
			
			var shipStruct:GCShipLoadObject = _shipList[_currentSid];
			var upgrades:Dictionary = new Dictionary();
			
			for each (var item:Object in details)
			{
				var slotId:uint = item["slotId"];
				var itemId:uint = item["itemId"];
				upgrades[slotId] = itemId;
			}
			
			shipStruct._upgrades = upgrades;
			
			if (_shipIdQueue.length > 0)
			{
				_loadingQueue.push(0);
				_currentSid = _shipIdQueue.pop();
				GCUtil.getShipEquipment(_currentSid, onLoadShipUpgrades);
			}
			
			loadingStageFinished();
		}
		
		/** Code to generate an 'email' like identifier, saving it on the flash cache **/
		public static function getSharedObject():SharedObject
		{
			return SharedObject.getLocal(SHARED_OBJECT_NAME);
		}
		
		/**
		 * Look for the bit of saved data in the flash cache that holds the player's email
		 * _loadingQueue length 0;
		 * @return
		 * 		Boolean of whether this is a returning player or not
		 */
		public function checkIfReturningPlayerAndGo():Boolean
		{
			if (GCConstants.FACEBOOK_INTEGRATED)
			{
				_loadingQueue.push(0);
				GCUtil.getPlayerInfo(_userUniqueId, onLoadPlayerData);
				return false;
			} else
			{
				var savedData:SharedObject = getSharedObject();
				if (savedData.data.username != null)
				{
					_userUniqueId = savedData.data.username as String;
					_playerName = savedData.data.playername as String;
					trace("Existing user logged in " + _userUniqueId);
					trace("Player name of user is " + _playerName);
					loadText.text = "Loading player data";
					_loadingQueue.push(0);
					GCUtil.getPlayerInfo(_userUniqueId, onLoadPlayerData);
					return true;
				}
				else
				{
					var generatedName:uint = (Math.random() * uint.MAX_VALUE);
					_userUniqueId = String(generatedName)
					trace("Generating new user name " + _userUniqueId);
					loadText.text = "Initialize new player";
					initializeNewPlayerData();
					return false;
				}
			}
		}
		
		
		/**
		 * Store a player's name into the flash cache, only do this after all data
		 * has been stored
		 */
		public static function storeNewPlayerInformation():void
		{
			trace("Saving a new player into the flash cache!");
			var savedData:SharedObject = getSharedObject();
			savedData.data.username = _userUniqueId;
			savedData.data.playername = _playerName;
			savedData.flush();
		}
	}
	
}